package com.github.lh

import com.alibaba.fastjson.annotation.JSONField
import java.util.*


class Block(
        val previousHash: String
) {

    var hash: String
    @JSONField(serialize = false)
    val transactions = ArrayList<Transaction>() //our data will be a simple message.
    private var merkleRoot: String = ""
    private val timeStamp: Long = Date().time
    @JSONField(serialize = false)
    private var nonce: Int = 0

    init {
        this.hash = calculateHash() //Making sure we do this after we set the other values.
    }

    //Calculate new hash based on blocks contents
    fun calculateHash(): String {
        return applySha256(
                previousHash +
                        java.lang.Long.toString(timeStamp) +
                        Integer.toString(nonce) +
                        merkleRoot
        )
    }

    //Increases nonce value until hash target is reached.
    fun mineBlock(difficulty: Int) {
        merkleRoot = getMerkleRoot(transactions)
        val target = getDificultyString(difficulty) //Create a string with difficulty * "0"
        while (hash.substring(0, difficulty) != target) {
            nonce++
            hash = calculateHash()
        }
        println("Block Mined!!! : " + hash)
    }

    //Add transactions to this block
    fun addTransaction(transaction: Transaction?): Boolean {
        //process transaction and check if valid, unless block is genesis block then ignore.
        return transaction?.run {
            if (previousHash !== "0") {
                if (!transaction.processTransaction().first) {
                    println("Transaction failed to process. Discarded.")
                    return false
                }
            }

            transactions.add(transaction)
            println("Transaction Successfully added to Block")
            return true
        }?: false
    }

}